var http = require('http')
  , WS = require('ws')//客户端刷新无法重新连接
  // , WebSocketServer = require('websocket').server//无效,可能是需要对应的客户端程序，不想测试了，因为socket.io也是这样的
  , SocketIo = require('socket.io')
  , url = require('url')
  , fs = require('fs');
 
var server = http.createServer(handler)

server.listen(10000);

switch (1) {
  case 1:
    SocketIoServerInstance();
    break;
  case 2:
    WSServerInstance()
    break;
  // case 3:
  //   WebSocketServerInstance();
  //   break;
}

function handler (req, res) {
  fs.readFile(__dirname + '../ns1.0/hotdocs/README.md', function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }
 
    res.writeHead(200);
    res.end(data);
  });
}

function NativeWebsocketServerInstance() {

}

// function WebSocketServerInstance() {
//   var websocketServer = new WebSocketServer({
//     httpServer: server,
//     // You should not use autoAcceptConnections for production 
//     // applications, as it defeats all standard cross-origin protection 
//     // facilities built into the protocol and the browser.  You should 
//     // *always* verify the connection's origin and decide whether or not 
//     // to accept it. 
//     autoAcceptConnections: true
//   });


//   websocketServer.on('connection', function(ws) {

//     console.log(ws)

//     ws.on('message', function(message) {
//       if (message.type === 'utf8') {
//         console.log('Received Message: ' + message.utf8Data);
//         ws.sendUTF(message.utf8Data);
//       } else if (message.type === 'binary') {
//         console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
//         ws.sendBytes(message.binaryData);
//       } else {
//         console.log(message)
//       }
//     });
//   });

//   websocketServer.on('close', function(ws, closeReason, description) {
//     console.log((new Date()) + ' Peer ' + ws.remoteAddress + ' disconnected.');
//   });

// }

function WSServerInstance() {
  const websocketServer = new WS.Server({ server });
 
  websocketServer.on('connection', function connection(ws) {
    const location = url.parse(ws.upgradeReq.url, true);
    // You might use location.query.access_token to authenticate or share sessions 
    // or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312)
    
    console.log('url: ', ws.upgradeReq.url)
   
    ws.on('message', function incoming(message) {
      console.log('received: %s', message);
      ws.send('Hello Client!');
    });

    var timeInterval = setInterval(function() {
      ws.send(Date.now());
    }, 2000);

    ws.on('close', function(message) {
      console.log('connection disconnect', message)
      clearInterval(timeInterval)
    })

    ws.on('error', function(message) {
      console.log('connection error', message)
      clearInterval(timeInterval)
    })
   
  });
}

function SocketIoServerInstance() {

  if (0) {
    //没有path默认的请求/socket.io/?EIO
    var websocketServer = SocketIo.listen(server);
  } else {
    //手动path
    var websocketServer = SocketIo(server, { path: '/api/ws/dataset' })
  }

  websocketServer.sockets.on('connection', function (ws) {
    ws.emit('push', { hello1: 'world' });
    ws.on('push_ack', function (data) {
      console.log('received push_ack: ', (new Date()).toString(), data);
    });


    var timeInterval = setInterval(function() {
      ws.emit('push', {time1: new Date().getTime()});
    }, 2000);

    ws.on('disconnect', function(message) {
      console.log('ws disconnect:', message)
      clearInterval(timeInterval)
    })

  });

  //可以理解为socket.io封装的逻辑path, 和emit的消息类型（形参1）同理
  websocketServer.of('/chat').on('connection', function (ws) {
    ws.emit('push', { hello2: 'world' });
    ws.on('push_ack', function (data) {
      console.log('received push_ack: ', (new Date()).toString(), data);
    });


    var timeInterval = setInterval(function() {
      ws.emit('push', {time2: new Date().getTime()});
    }, 2000);

    ws.on('disconnect', function(message) {
      console.log('ws /chat disconnect:', message)
      clearInterval(timeInterval)
    })

  });

}